home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
-
- tescroll.c
-
- This reusable module manages simple TextEdit fields with vertical
- scroll bars.
-
- Copyright © 1994-1995, Northwestern University.
-
- ----------------------------------------------------------------------------*/
-
- #include "def.h"
- #include "tescroll.h"
- #include "teutil.h"
-
-
-
-
- /*----------------------------------------------------------------------------
- TEScrollNumTELines
-
- Get the number of lines in a TE field.
-
- Entry: theTE = handle to TextEdit record.
-
- Exit: function result = number of lines in field.
- ----------------------------------------------------------------------------*/
-
- short TEScrollNumTELines (TEHandle theTE)
- {
- short nLines;
- Handle hText;
- short teLength;
-
- nLines = (**theTE).nLines;
- if (nLines == 0) {
- nLines = 1;
- } else {
- hText = (**theTE).hText;
- teLength = (**theTE).teLength;
- if (*(*hText + teLength - 1) == CR) nLines++;
- }
- return nLines;
- }
-
-
-
- /*----------------------------------------------------------------------------
- TEScrollGetTELineNumber
-
- Get the line number of a character position in a TextEdit field.
-
- Entry: charPos = character position (0-based).
- theTE = handle to TextEdit record.
-
- Exit: function result = line number (0-based).
- ----------------------------------------------------------------------------*/
-
- short TEScrollGetTELineNumber (short charPos, TEHandle theTE)
- {
- short *lineStarts;
- short nLines;
- short i;
- Handle hText;
-
- lineStarts = (**theTE).lineStarts;
- nLines = (**theTE).nLines;
- i = 0;
- while (i <= nLines && *lineStarts <= charPos) {
- i++;
- lineStarts++;
- }
- if (i == 0) return 0;
- i--;
- if (*(lineStarts-1) != charPos) return i;
- if (i == 0) return 0;
- hText = (**theTE).hText;
- return MyGetClikStuff(theTE) == 0 ? i-1 : i;
- }
-
-
-
- /*----------------------------------------------------------------------------
- TEScrollAdjustScrollMax
-
- Adjust the scroll bar maximum value.
-
- Entry: theTE = handle to TextEdit record.
- vScroll = handle to scroll bar control.
- ----------------------------------------------------------------------------*/
-
- void TEScrollAdjustScrollMax (TEHandle theTE, ControlHandle vScroll)
- {
- Rect viewRect, destRect;
- short max, viewHeight;
- short nLines, bottom, height, lineHeight;
-
- lineHeight = (**theTE).lineHeight;
- viewRect = (**theTE).viewRect;
- destRect = (**theTE).destRect;
- nLines = TEScrollNumTELines(theTE);
- viewHeight = viewRect.bottom - viewRect.top;
- bottom = destRect.top + nLines*lineHeight;
- if (bottom < viewRect.bottom) bottom = viewRect.bottom;
- height = bottom - destRect.top;
- max = height - viewHeight;
- if (max < 0) max = 0;
- SetControlMaximum(vScroll, max/lineHeight);
- }
-
-
-
- /*----------------------------------------------------------------------------
- TEScrollScrollText
-
- Scroll text.
-
- Entry: theTE = handle to TextEdit record.
- vScroll = handle to scroll bar control.
- dv = number of lines to scroll.
-
- If the scroll bar's refCon is non-zero, the scroll bar max value is
- adjusted after the scrolling operation. This is what you normally want.
- The only exception is when scrolling in a TrackControl action procedure,
- when you want to set the refCon to zero.
- ----------------------------------------------------------------------------*/
-
- void TEScrollScrollText (TEHandle theTE, ControlHandle vScroll, short dv)
- {
- short lineHeight;
-
- lineHeight = (**theTE).lineHeight;
- TEScroll(0, dv * lineHeight, theTE);
- if (GetControlReference(vScroll) != 0) TEScrollAdjustScrollMax(theTE, vScroll);
- }
-
-
-
- /*----------------------------------------------------------------------------
- TEScrollScrollRangeIntoView
-
- Scroll a range of characters into view, if necessary.
-
- Entry: theTE = handle to TextEdit record.
- start = starting offset of range.
- end = ending offset of range.
- vScroll = handle to scroll bar control.
- ----------------------------------------------------------------------------*/
-
- void TEScrollScrollRangeIntoView (TEHandle theTE, short start, short end,
- ControlHandle vScroll)
- {
- short lineStart, lineEnd, top, lineHeight, vStart, vEnd;
- short oldScrollVal, max, dv;
- Rect viewRect;
- Boolean tooBig;
- short selStart, selEnd, savedClikStuff;
-
- TEScrollAdjustScrollMax(theTE, vScroll);
- savedClikStuff = (**theTE).clikStuff;
- selStart = (**theTE).selStart;
- selEnd = (**theTE).selEnd;
- if (start == end && selStart < selEnd) {
- if (start == selEnd) {
- (**theTE).clikStuff = 0;
- } else if (end == selStart) {
- (**theTE).clikStuff = 0xffff;
- }
- lineStart = TEScrollGetTELineNumber(start, theTE);
- lineEnd = TEScrollGetTELineNumber(end, theTE);
- } else if (start < end) {
- (**theTE).clikStuff = 0xffff;
- lineStart = TEScrollGetTELineNumber(start, theTE);
- (**theTE).clikStuff = 0;
- lineEnd = TEScrollGetTELineNumber(end, theTE);
- } else {
- lineStart = TEScrollGetTELineNumber(start, theTE);
- lineEnd = TEScrollGetTELineNumber(end, theTE);
- }
- (**theTE).clikStuff = savedClikStuff;
- top = (**theTE).destRect.top;
- lineHeight = (**theTE).lineHeight;
- vStart = top + lineStart*lineHeight;
- vEnd = top + (lineEnd+1)*lineHeight;
- viewRect = (**theTE).viewRect;
- tooBig = (vEnd - vStart) > (viewRect.bottom - viewRect.top);
- if (vEnd > viewRect.bottom) {
- if (vStart < viewRect.bottom - lineHeight) return;
- if (tooBig) {
- dv = viewRect.top - vStart;
- } else {
- dv = viewRect.bottom - vEnd;
- }
- } else if (vStart < viewRect.top) {
- if (vEnd > viewRect.top + lineHeight) return;
- if (tooBig) {
- dv = viewRect.bottom - vEnd;
- } else {
- dv = viewRect.top - vStart;
- }
- } else {
- TEScrollAdjustScrollMax(theTE, vScroll);
- return;
- }
- dv = dv/lineHeight;
- oldScrollVal = GetControlValue(vScroll);
- max = GetControlMaximum(vScroll);
- if (oldScrollVal - dv > max) dv = oldScrollVal - max;
- TEScrollScrollText(theTE, vScroll, dv);
- SetControlValue(vScroll, oldScrollVal - dv);
- }
-
-
-
- /*----------------------------------------------------------------------------
- TEScrollScrollSelectionIntoView
-
- Scroll the current selection into view, if necessary.
-
- Entry: theTE = handle to TextEdit record.
- vScroll = handle to scroll bar control.
- ----------------------------------------------------------------------------*/
-
- void TEScrollScrollSelectionIntoView (TEHandle theTE, ControlHandle vScroll)
- {
- TEScrollScrollRangeIntoView(theTE, (**theTE).selStart, (**theTE).selEnd,
- vScroll);
- }
-
-
-
- /*----------------------------------------------------------------------------
- TEScrollScrollToMiddle
-
- Scroll a given point in the text to the middle of the view, if necessary.
-
- Entry: theTE = handle to TextEdit record.
- offset = offset of character to scroll to middle.
- vScroll = handle to scroll bar control.
- ----------------------------------------------------------------------------*/
-
- void TEScrollScrollToMiddle (TEHandle theTE, short offset, ControlHandle vScroll)
- {
- short lineStart, top, lineHeight, vStart;
- short oldScrollVal, max, dv, viewHeight;
- Rect viewRect;
- short savedClikStuff;
-
- TEScrollAdjustScrollMax(theTE, vScroll);
- savedClikStuff = (**theTE).clikStuff;
- (**theTE).clikStuff = 0xffff;
- lineStart = TEScrollGetTELineNumber(offset, theTE);
- (**theTE).clikStuff = savedClikStuff;
- top = (**theTE).destRect.top;
- lineHeight = (**theTE).lineHeight;
- vStart = top + lineStart*lineHeight;
- viewRect = (**theTE).viewRect;
- if (vStart >= viewRect.top && vStart <= viewRect.bottom - lineHeight) return;
- viewHeight = (viewRect.bottom - viewRect.top) / lineHeight;
- dv = (viewRect.top - vStart)/lineHeight + (viewHeight >> 1);
- oldScrollVal = GetControlValue(vScroll);
- max = GetControlMaximum(vScroll);
- if (oldScrollVal - dv > max) dv = oldScrollVal - max;
- TEScrollScrollText(theTE, vScroll, dv);
- SetControlValue(vScroll, oldScrollVal - dv);
- }
-
-
-
- /*----------------------------------------------------------------------------
- TEScrollScrollByPartCode
-
- Scroll text by part code.
-
- Entry: theTE = handle to TextEdit record.
- vScroll = handle to scroll bar control.
- part = part code.
- ----------------------------------------------------------------------------*/
-
- void TEScrollScrollByPartCode (TEHandle theTE, ControlHandle vScroll, short part)
- {
- short val, max, page, dv;
-
- page = GetTEPageHeight(theTE);
- val = (**vScroll).contrlValue;
- max = (**vScroll).contrlMax;
- dv = 0;
- switch (part) {
- case inUpButton:
- dv = val > 0 ? 1 : 0;
- break;
- case inDownButton:
- dv = val < max ? -1 : 0;
- break;
- case inPageUp:
- dv = val > page ? page : val;
- break;
- case inPageDown:
- dv = val < max ? -page : 0;
- break;
- case kScrollToHome:
- dv = val;
- break;
- case kScrollToEnd:
- dv = val - max;
- break;
- }
- if (dv != 0) {
- TEScrollScrollText(theTE, vScroll, dv);
- TEScrollAdjustScrollMax(theTE, vScroll);
- SetControlValue(vScroll, val - dv);
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- TEScrollAutoScroll
-
- Handle text autoscrolling.
-
- Entry: theTE = handle to TextEdit record.
- vScroll = handle to scroll bar control.
-
- Exit: function result = true
- ----------------------------------------------------------------------------*/
-
- void TEScrollAutoScroll (TEHandle theTE, ControlHandle vScroll)
- {
- Rect viewRect;
- Point where;
- short val, max;
-
- val = GetControlValue(vScroll);
- max = GetControlMaximum(vScroll);
- viewRect = (**theTE).viewRect;
- GetMouse(&where);
- ClipRect(&qd.thePort->portRect);
- if (where.v < viewRect.top && val > 0) {
- TEScrollScrollText(theTE, vScroll, 1);
- SetControlValue(vScroll, val-1);
- } else if (where.v > viewRect.bottom && val < max) {
- TEScrollScrollText(theTE, vScroll, -1);
- SetControlValue(vScroll, val+1);
- }
- ClipRect(&viewRect);
- }
-